﻿using System;
using System.Collections.Generic;

namespace Share
{
    /// <summary>
    /// EventParamCommon类提供了一个通用的事件参数管理方式，继承自EventParam。
    /// 它允许开发者添加、获取和移除事件参数，这些参数以键值对的形式存储。
    /// </summary>
    public class EventParamCommon : EventParam
    {
        /// <summary>
        /// 创建并返回一个新的EventParamCommon实例。
        /// </summary>
        /// <returns>一个新的EventParamCommon实例。</returns>
        public static EventParamCommon New() => new EventParamCommon();

        /// <summary>
        /// 存储事件参数的字典，键为参数名，值为参数值。
        /// </summary>
        private Dictionary<string, object> m_GenericData = new Dictionary<string, object>();

        #region 赋值操作

        /// <summary>
        /// 向事件参数中添加键值对数据。
        /// 如果键已存在，则更新该键的值；如果键不存在，则添加新的键值对。
        /// </summary>
        /// <param name="key">参数名。</param>
        /// <param name="value">参数值。</param>
        /// <typeparam name="T">参数值的类型。</typeparam>
        public void AddData<T>(string key, T value)
        {
            if (key == null) throw new ArgumentNullException(nameof(key));
            if (m_GenericData.ContainsKey(key))
                m_GenericData[key] = value;
            else
                m_GenericData.Add(key, value);
        }


        #endregion

        #region 取值操作

        /// <summary>
        /// 根据键获取事件参数的值。
        /// 如果键存在且值的类型与指定的泛型类型匹配，则返回该值；否则返回默认值。
        /// </summary>
        /// <param name="key">参数名。</param>
        /// <typeparam name="T">期望获取的参数值类型。</typeparam>
        /// <returns>参数值或默认值。</returns>
        public T GetData<T>(string key)
        {
            if (m_GenericData.TryGetValue(key, out var value) && value is T typedValue)
                return typedValue;
            return default(T);
        }

        /// <summary>
        /// 检查事件参数中是否包含指定键的数据。
        /// </summary>
        /// <param name="key">参数名。</param>
        /// <returns>如果包含指定键的数据，则返回true；否则返回false。</returns>
        public bool IsHaveData(string key) => m_GenericData.ContainsKey(key);


        #endregion

        /// <summary>
        /// 清空所有事件参数。
        /// </summary>
        public void Clear() => m_GenericData.Clear();

        /// <summary>
        /// 根据键移除事件参数。
        /// 如果键存在，则移除该键值对；否则不进行任何操作。
        /// </summary>
        /// <param name="key">参数名。</param>
        public void RemoveData(string key)
        {
            if (m_GenericData.ContainsKey(key))
                m_GenericData.Remove(key);
        }

        /// <summary>
        /// 重写ToString方法，返回所有事件参数的字符串表示。
        /// </summary>
        /// <returns>包含所有事件参数的字符串。</returns>
        public override string ToString()
        {
            string str = "EventParamCommon\n";
            foreach (var item in m_GenericData)
            {
                str += $"[{item.Key}]={item.Value}\n";
            }
            return str;
        }

        /// <summary>
        /// 创建当前EventParamCommon实例的深度克隆。
        /// 克隆的实例将包含与当前实例相同的键值对。
        /// </summary>
        /// <returns>当前实例的深度克隆。</returns>
        public override EventParam DeepClone()
        {
            var clone = new EventParamCommon();
            foreach (var kvp in m_GenericData)
            {
                clone.AddData(kvp.Key, kvp.Value);
            }
            return clone;
        }

        /// <summary>
        /// 将另一个EventParamCommon实例的数据合并到当前实例中。
        /// 如果other不是EventParamCommon类型，则不进行任何操作并返回false。
        /// </summary>
        /// <param name="other">要合并的另一个EventParam实例。</param>
        /// <returns>如果合并成功，则返回true；否则返回false。</returns>
        public override bool Combin(EventParam other)
        {
            if (other is EventParamCommon otherCommon)
            {
                foreach (var kvp in otherCommon.m_GenericData)
                {
                    m_GenericData[kvp.Key] = kvp.Value;
                }
                return true;
            }
            return false;
        }
    }
}